using UnityEngine;
using System.Collections;

public class InputManager : MonoBehaviour {
	
	//Mouse Keycodes
	KeyCode LEFT_CLICK = KeyCode.Mouse0;
	KeyCode RIGHT_CLICK = KeyCode.Mouse1;
	//Keyboard Keycodes
	KeyCode CROUCHKEY = KeyCode.LeftControl;
	KeyCode VISIONKEY = KeyCode.LeftShift;
    KeyCode INVENTORY = KeyCode.V;
    KeyCode STATS = KeyCode.C;
    KeyCode PAUSE = KeyCode.Escape;
    KeyCode LOCKONKEY = KeyCode.Space;
    KeyCode SOUNDVISUALKEY = KeyCode.F;
    KeyCode DROPCORPSEKEY = KeyCode.E;
    KeyCode UNEQUIP = KeyCode.Q;


    KeyCode CHARACTER1 = KeyCode.F1;
    KeyCode CHARACTER2 = KeyCode.F2;
    KeyCode CHARACTER3 = KeyCode.F3;
    KeyCode CHARACTER4 = KeyCode.F4;
	
	KeyCode HOTKEY1 = KeyCode.Alpha1;
	KeyCode HOTKEY2 = KeyCode.Alpha2;
	KeyCode HOTKEY3 = KeyCode.Alpha3;
    //Para saber si se apreto un click en el frame anterior
    //Asi algunas funciones funcionan manteniendo y otras no.
    bool m_PressedPrev = false;
	
	private gameState actualGameState;
	
	enum gameState {
		GUI_OPEN,
		INGAME
	}
	void Start () 
    {
		actualGameState = gameState.INGAME;
	}
	

	void Update () 
    {
        if (Input.GetKeyDown(PAUSE) && GameManager.GetInstance().IsGameFinished() == false)
        {
            GameManager.GetInstance().Pause();
        }
        if (GameManager.GetInstance().IsPaused() == false)
        {
            ReadKeyInputs();
        }
        SetCursorTexture();
        if (InventoryController.GetInstance().IsOpened())
            return;
        ReadMouseInput();
		
	}
    /// <summary>
    /// 
    /// </summary>
    /// <returns>Devuelve que boton del mouse se toco. KeyCode.none si no se toco ninguno</returns>
	KeyCode GetMouseInput(){
		KeyCode mButton = KeyCode.None;
		if (Input.GetKey(LEFT_CLICK) )
			mButton = LEFT_CLICK;
		else if (Input.GetKey(RIGHT_CLICK) )
			mButton = RIGHT_CLICK;
		return mButton;
	}
    /// <summary>
    /// Lee los inputs de tecla
    /// </summary>
    void ReadKeyInputs()
    {
        CharacterSelectionInput();
        if (Input.GetKeyDown(CROUCHKEY))
        {
            Player.instance.CrouchUnit();
        }
        else if (Input.GetKeyDown(INVENTORY))
        {
            Player.instance.OpenInventory();
        }
        else if (Input.GetKeyDown(STATS))
        {
            Player.instance.ShowStats();
        }
        else if (Input.GetKeyDown(SOUNDVISUALKEY))
        {
            VisionManager.GetInstance().ToggleSoundVisual();
        }
        else if (Input.GetKeyDown(DROPCORPSEKEY))
        {
            Player.instance.GetSelectedCharacter().DropCorpse();
        }
        else if (Input.GetKeyDown(UNEQUIP))
        {
            Player.instance.UnEquip();
        }

        //item hotkeys
        if (Input.GetKeyDown(HOTKEY1))
        {
            Player.instance.UseHotSkills(0);
        }
        else if (Input.GetKeyDown(HOTKEY2))
        {
            Player.instance.UseHotSkills(1);
        }
        else if (Input.GetKeyDown(HOTKEY3))
        {
            Player.instance.UseHotSkills(2);
        }
        if (Input.GetKey(LOCKONKEY))
        {
            Character c = Player.instance.GetSelectedCharacter();

            if (c != null)
            {
                CameraOmniVision.GetInstance().TranslateToPosition(c.transform.position);
            }
        }
    }
    void CharacterSelectionInput()
    {
        int selectIndex = -1;
        if (Input.GetKeyDown(CHARACTER1))
        {
            selectIndex = 0;
        }
        else if (Input.GetKeyDown(CHARACTER2))
        {
            selectIndex = 1;
        }
        else if (Input.GetKeyDown(CHARACTER3))
        {
            selectIndex = 2;
        }
        else if (Input.GetKeyDown(CHARACTER4))
        {
            selectIndex = 3;
        }

        if (selectIndex != -1)
        {
            Character c = Player.instance.GetSelectedCharacter();
            if (c != null)
            {
                if (c.m_CharacterIndex == selectIndex)
                {
                    CameraOmniVision.GetInstance().TranslateToPosition(c.transform.position);
                    return;
                }
            }
            Player.instance.SelectCharacter(selectIndex);
        }
    }
    void ReadMouseInput()
    {
        KeyCode mouseButton = GetMouseInput();
        if (mouseButton != KeyCode.None)
        {
            Ray ray;
            RaycastHit raycastHitInfo;

            ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out raycastHitInfo))
            {
                if (raycastHitInfo.collider != null)
                {
                    if (mouseButton == LEFT_CLICK)
                    {
                        DoMainAction(raycastHitInfo);
                    }
                    else if (mouseButton == RIGHT_CLICK)
                    {
                        DoSecondaryAction(raycastHitInfo);
                    }
                }
            }
            m_PressedPrev = true;
        }
        else
        {
            m_PressedPrev = false;
        }
    }
	private void PickItem(RaycastHit raycastHitInfo){
			Item item = raycastHitInfo.collider.transform.parent.GetComponent<Item>();
			item.OnRightClic(raycastHitInfo.point);
	}
	private void DoMainAction(RaycastHit raycastHitInfo)
    {
        if (raycastHitInfo.collider != null)
        {
            switch (raycastHitInfo.transform.gameObject.layer)
            {
                case 10: //dead enemy
                    Enemy e = raycastHitInfo.transform.GetComponent<Enemy>();
                    if (e != null && !m_PressedPrev)
                    { 
                        if (Player.instance.GetSelectedCharacter() != null && Player.instance.GetSelectedCharacter().CanDragCorpses())
                        {
                            Player.instance.GetSelectedCharacter().DragCorpse(e);
                        }
                    }
                break;
                default:

                    if (Input.GetKey(VISIONKEY))
                    {
                        if(!m_PressedPrev)
                        {
                            Enemy enemy = raycastHitInfo.transform.GetComponent<Enemy>();
                            if (enemy != null)
                                VisionManager.GetInstance().SelectEnemy(enemy);
                        }
                        return;
                    }

                    Character c = raycastHitInfo.transform.GetComponent<Character>();
                    if (c != null)
                    {
                        if (!m_PressedPrev)
                        {
                            Player.instance.SelectCharacter(c);
                        }
                    }
                    else
                    {
                        //Debug.Log("use equippable");
                        Player.instance.UseEquipable(raycastHitInfo);
                    }
                break;
            }
        }
	}
	private void DoSecondaryAction(RaycastHit raycastHitInfo)
    {
        if (m_PressedPrev) return;
        if (raycastHitInfo.collider != null)
        {
            switch (raycastHitInfo.transform.gameObject.layer)
            {
                case 9: //item
                    Player.instance.PickUpItem(raycastHitInfo);
                break;
                case 10: //dead enemy
                    Enemy e = raycastHitInfo.transform.GetComponent<Enemy>();
                    if (e != null)
                    {
                        if (e.m_AvailableLoot != null)
                        {
                            Player.instance.PickUpItem(e.m_AvailableLoot);
                        }
                    }
                break;
                default: //si no hay layer
                    Player.instance.MoveUnit(raycastHitInfo.point);
                break;
            }
        }
	}
    public void SetCursorTexture()
    {
        bool useWeaponCursor = false;
        Ray ray;
        RaycastHit raycastHitInfo;

        ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        MouseController.CursorType cursorToUse = MouseController.CursorType.DEFAULT;

        //si no tengo abierto algun menu
        if (InventoryController.GetInstance().IsOpened() == false)
        {
            if (Physics.Raycast(ray, out raycastHitInfo))
            {
                if (raycastHitInfo.collider != null)
                {
                    Character selected = Player.instance.GetSelectedCharacter();
                    if (Input.GetKey(VISIONKEY) && raycastHitInfo.transform.GetComponent<Enemy>() != null)
                    {
                        cursorToUse = MouseController.CursorType.EYE;
                    }
                    else if (selected != null)
                    {
                        //item
                        if (raycastHitInfo.transform.gameObject.layer == 9)
                        {
                            cursorToUse = MouseController.CursorType.LOOT;
                        }
                        //Layer 10 es la de enemigo muerto
                        else if (raycastHitInfo.transform.gameObject.layer == 10 )
                        {
                            Enemy e = raycastHitInfo.transform.GetComponent<Enemy>();
                            if (e != null)
                            {
                                if (e.m_AvailableLoot != null)
                                {
                                    cursorToUse = MouseController.CursorType.LOOT;
                                }
                                else if (selected.CanDragCorpses())
                                {
                                    cursorToUse = MouseController.CursorType.HAND;
                                }
                            }
                            else
                            {
                                useWeaponCursor = true;
                            }
                        }
                        else
                        {
                            useWeaponCursor = true;
                        }
                        if(useWeaponCursor)
                        {
                            Equipable equipped = selected.GetEquippable();
                            if (equipped != null)
                            {
                                if (equipped is KnifeBehaviour)
                                {
                                    //layer de enemigo
                                    if (raycastHitInfo.transform.gameObject.layer == 14)
                                    {
                                        cursorToUse = MouseController.CursorType.KNIFEACTIVE;
                                    }
                                    else
                                    {
                                        cursorToUse = MouseController.CursorType.KNIFE;
                                    }
                                }
                                else if (equipped is WeaponBehaviour)
                                {
                                    //si me da el rango uso la mira.
                                    if (Vector3.Distance(raycastHitInfo.point, selected.GetMountingPoint()) >= equipped.m_UseRange)
                                    {
                                        cursorToUse = MouseController.CursorType.FORBIDDEN;
                                    }
                                    else
                                    {
                                        //layer de enemigo
                                        if (raycastHitInfo.transform.gameObject.layer == 14)
                                        {
                                            cursorToUse = MouseController.CursorType.AIMACTIVE;
                                        }
                                        else
                                        {
                                            HittableObject ho = raycastHitInfo.transform.GetComponent<HittableObject>();
                                            if (ho != null)
                                            {
                                                cursorToUse = MouseController.CursorType.AIMACTIVE;
                                            }
                                            else
                                            {
                                                cursorToUse = MouseController.CursorType.AIM;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        MouseController.instance.ChangeCursor(cursorToUse);
    }

}

		/*	if (Physics.Raycast(ray, out raycastHitInfo) ){
				if (raycastHitInfo.collider != null ){
					switch(mouseButton){
					case 8://Unit
						if (mouseButton == LEFT_CLICK)
							MainAction(raycastHitInfo);
						break;
					case 9://Item-World
						if (mouseButton == RIGHT_CLICK)
							PickItem(raycastHitInfo);
						break;
					default://Si no hay layer
						if (mouseButton == RIGHT_CLICK)
							SecondaryAction(raycastHitInfo);
						break;
					}*/
